package com.lagou.edu.controller;

import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @param
 * @author oyz
 * @version 1.0
 * @description: TODO
 * @date 2022/4/26 8:59
 */
@RestController
@RequestMapping("autodeliver")
public class AutodeliverController {


    @Autowired
    @Qualifier("eurekaClient")
    private EurekaClient eurekaClient;


    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("checkStateRestTemplate/{userId}")
    public Integer findResumeOpenStateByRestTemplate(@PathVariable Long userId){
        Integer forObject = restTemplate.getForObject("http://localhost:8080/resume/close/" + userId, Integer.class);
        return forObject;
    }

    /**
     * eureka服务化的改造
     * @param userId
     * @return
     */
    @GetMapping("checkState2/{userId}")
    public Integer findResumeOpenState2(@PathVariable Long userId){
        List<InstanceInfo> instances = eurekaClient.getInstancesById("192.168.220.1:lagou-sservice-resume:8080:1.0-SNAPSHOT");
        // 如果有多个实例,选择一个使用(负载均衡的过程)
        InstanceInfo instanceInfo = instances.get(0);
        String ipAddr = instanceInfo.getIPAddr();
        int port = instanceInfo.getPort();
        String url = "http://" + ipAddr + ":" + port +"/resume/openstate/" + userId;

        Integer forObject = restTemplate.getForObject(url, Integer.class);
        return forObject;
    }

    /**
     * 测试ribbon负载均衡
     * @param userId
     * @return
     */
    @GetMapping("checkState/{userId}")
    public Integer findResumeOpenState(@PathVariable Long userId){
        // 使用ribbon
        String url = "http://lagou-sservice-resume/resume/openstate/" + userId;

        Integer forObject = restTemplate.getForObject(url, Integer.class);
        return forObject;
    }


    /**
     * 提供者模拟请求超时,调用方法添加Hystrix控制
     * @param userId
     * @return
     */
    @GetMapping("checkStateTimeOut/{userId}")
    @HystrixCommand(
            // 线程池标识
            threadPoolKey = "findResumeOpenStateTimeOut",
            // 线程池细节属性配置
            threadPoolProperties = {
                @HystrixProperty(name="coreSize",value = "2"),
                @HystrixProperty(name="maxQueueSize",value = "20")
            },
            commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "2000")},
            fallbackMethod = "fallBack"
    )
    public Integer findResumeOpenStateTimeOut(@PathVariable Long userId){
        // 使用ribbon
        String url = "http://lagou-sservice-resume/resume/openstate/" + userId;

        Integer forObject = restTemplate.getForObject(url, Integer.class);
        return forObject;
    }


    /**
     * 提供者模拟请求超时,调用方法添加Hystrix控制
     * @param userId
     * @return
     */
    @GetMapping("checkStateTimeOutFallback/{userId}")
    @HystrixCommand(
            // 线程池标识
            threadPoolKey = "findResumeOpenStateTimeOutFallback",
            // 线程池细节属性配置
            threadPoolProperties = {
                    @HystrixProperty(name="coreSize",value = "1"),
                    @HystrixProperty(name="maxQueueSize",value = "20")
            },
            commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "2000"),
                    //Hystrix高级配置,定制工作过程细节

            @HystrixProperty(name =
                    "metrics.rollingStats.timeInMilliseconds",value = "8000"),
            @HystrixProperty(name =
                    "circuitBreaker.requestVolumeThreshold",value = "2"),
            @HystrixProperty(name =
                    "circuitBreaker.errorThresholdPercentage",value = "50"),
            @HystrixProperty(name =
                    "circuitBreaker.sleepWindowInMilliseconds",value = "3000")
            },
            fallbackMethod = "fallBack"
    )
    public Integer findResumeOpenStateTimeOutFallback(@PathVariable Long userId){
        // 使用ribbon
        String url = "http://lagou-sservice-resume/resume/openstate/" + userId;

        Integer forObject = restTemplate.getForObject(url, Integer.class);
        return forObject;
    }

    /**
     * @description: 回退方法
     * @author oyz
     * @param userId
     * @date 2022/5/2 12:54
     * @version 1.0
     */
    public Integer fallBack(Long userId){
        return -1;
    }
}
